#include<iostream>
using namespace std;

#include<stack>
#include<queue>
#include <time.h>
#include <algorithm>

#include"Stack.h"
#include"Queue.h"
#include"PriorityQueue.h"

void test_stack()
{
	//ltw::stack<int, vector<int>> s;
	//ltw::stack<int, list<int>> s;
	ltw::stack<int, deque<int>> s;

	//ltw::stack<int> s;

	s.push(1);
	s.push(2);
	s.push(3);
	s.push(4);

	while (!s.empty())
	{
		cout << s.top() << " ";
		s.pop();
	}
	cout << endl;
}


void test_queue()
{
	ltw::queue<int> q;
	//ltw::queue<int,list<int>> q;

	// 不支持
	//ltw::queue<int, vector<int>> q;

	q.push(1);
	q.push(2);
	q.push(3);
	q.push(4);

	while (!q.empty())
	{
		cout << q.front() << " ";
		q.pop();
	}
	cout << endl;
}

void test_op1()
{
	srand(time(0));
	const int N = 1000000;

	deque<int> dq;
	vector<int> v;

	for (int i = 0; i < N; ++i)
	{
		auto e = rand() + i;
		v.push_back(e);
		dq.push_back(e);
	}

	int begin1 = clock();
	sort(v.begin(), v.end());
	int end1 = clock();

	int begin2 = clock();
	sort(dq.begin(), dq.end());
	int end2 = clock();

	printf("vector:%d\n", end1 - begin1);
	printf("deque:%d\n", end2 - begin2);
}

void test_op2()
{
	srand(time(0));
	const int N = 1000000;

	deque<int> dq1;
	deque<int> dq2;

	for (int i = 0; i < N; ++i)
	{
		auto e = rand() + i;
		dq1.push_back(e);
		dq2.push_back(e);
	}

	int begin1 = clock();
	sort(dq1.begin(), dq1.end());
	int end1 = clock();

	int begin2 = clock();
	// 拷贝到vector
	vector<int> v(dq2.begin(), dq2.end());
	sort(v.begin(), v.end());
	dq2.assign(v.begin(), v.end());
	int end2 = clock();

	printf("deque sort:%d\n", end1 - begin1);
	printf("deque copy vector sort, copy back deque:%d\n", end2 - begin2);
}

// 默认是大堆
void test_priority_queue()
{
	//vector<int> v = { 3,2,7,6,0,4,1,9,8,5 };
	///*priority_queue<int> q1;
	//for (auto& e : v)
	//	q1.push(e);*/

	//priority_queue<int> q1(v.begin(), v.end());

	int a[] = { 3,2,7,6,0,4,1,9,8,5 };
	// 默认是大堆
	//ltw::priority_queue<int> q1(a, a+sizeof(a)/sizeof(int));
	// 小堆
	ltw::priority_queue<int, vector<int>, ltw::mygreater<int>> q1(a, a + sizeof(a) / sizeof(int));

	while (!q1.empty())
	{
		cout << q1.top() << " ";
		q1.pop();
	}
	cout << endl;
}

// 仿函数/函数对象:重载了operator()的类,类的对象可以像函数一样使用
// operator()特点，参数个数和返回值根据需求确定，不固定，很灵活
class Func
{
public:
	void operator()(int n)
	{
		while (n--)
		{
			cout << "Func调用" << endl;
		}
		cout << endl;
	}
};

template<class T>
class myless
{
public:
	bool operator()(const T& x, const T& y)
	{
		return x < y;
	}
};

int main()
{
	Func f1;
	f1(10);
	f1.operator()(10);

	myless<int> lessFunc1;
	cout << lessFunc1(1, 2) << endl;
	// lessFunc1.operator()(1,2);

	myless<string> lessFunc2;
	cout << lessFunc2("1111", "22222") << endl;


	test_stack();
	test_queue();
	// test_priority_queue();

	//test_op2();

	return 0;
}

// void PushBack(int x)
// {
// 	printf("void PushBack(int x)\n");
// }

// // C
// struct Vector
// {
// 	void(*push_back)(int);

// 	int* _a;
// 	int _size;
// 	int _capacity;
// };

// void Init(struct Vector* pv)
// {
// 	pv->push_back = PushBack;
// 	//...
// }

// int main()
// {
// 	Vector v;
// 	Init(&v);

// 	v.push_back(1);
// 	v.push_back(2);

// 	return 0;
// }

//////////////////////////////////////////////////////////////
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}

	bool operator<(const Date& d)const
	{
		return (_year < d._year) ||
			(_year == d._year && _month < d._month) ||
			(_year == d._year && _month == d._month && _day < d._day);
	}

	bool operator>(const Date& d)const
	{
		return (_year > d._year) ||
			(_year == d._year && _month > d._month) ||
			(_year == d._year && _month == d._month && _day > d._day);
	}

	friend ostream& operator<<(ostream& _cout, const Date& d);
private:
	int _year;
	int _month;
	int _day;
};

ostream& operator<<(ostream& _cout, const Date& d)
{
	_cout << d._year << "-" << d._month << "-" << d._day;
	return _cout;
}

struct PDateLess
{
	bool operator()(Date* p1, Date* p2)
	{
		return *p1 < *p2;
	}
};

void TestPriorityQueue()
{
	// 大堆，需要用户在自定义类型中提供<的重载
	ltw::priority_queue<Date*, vector<Date*>, PDateLess> q1;
	q1.push(new Date(2018, 10, 29));
	q1.push(new Date(2018, 10, 28));
	q1.push(new Date(2018, 10, 30));

	while (!q1.empty())
	{
		cout << *q1.top() << " ";
		q1.pop();
	}
	cout << endl;
}

int main()
{
	TestPriorityQueue();

	return 0;
}